package cc.owoo.godpen.analysis.json;

import cc.owoo.godpen.analysis.Retract;
import cc.owoo.godpen.analysis.StringAnalysis;
import cc.owoo.godpen.file.SuperFile;
import cc.owoo.godpen.reflect.GenericityType;
import cc.owoo.godpen.reflect.Translate;
import cc.owoo.godpen.util.N;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * Json转换对象，可以将java对象和json字符串进行互相转换。
 * <p>
 * 不建议直接使用Json对象来操作值，比如频繁调用get函数，这些函数是为方便调用者用少量的代码获取想要的值用的，如果需要频繁操作数据，请转换为实体类后再操作。
 * <p>
 * Created by nimensei
 * 2022-05-16 上午 10:12
 **/
public abstract class Json {
    private static final N.CharacterTranslate TRANSLATE_ENABLE = N::escape;// 字符转换
    private static final N.CharacterTranslate TRANSLATE_DISABLED = c -> c == '"' ? "\\\"" : String.valueOf(c);// 字符转换

    public static final int CONFIG_FORMAT = 0b1;// 格式化
    public static final int CONFIG_UNICODE = 0b10;// 将非ASCII字符转换成unicode编码
    public static final int CONFIG_NON_ESCAPE = 0b100;// 不使用转义字符，如缩进、回车等字符保持不变
    public static final int CONFIG_EMPTY = 0b1000;// 包含值为null的键值对

    /**
     * 构建一个Json对象
     *
     * @param object 需要创建的数据
     */
    public static Json create(Object object) {
        if (object instanceof Json json)
            return json;
        if (object == null)
            return new JsonNull();
        if (object.getClass().isArray())
            return new JsonArray(object);
        if (object instanceof Map<?, ?> map)
            return new JsonMap((Map<Object, Object>) map);
        if (object instanceof List<?> list)
            return new JsonList((List<Object>) list);
        if (object instanceof CharSequence string)
            return new JsonString(string);
        if (object instanceof Number number)
            return new JsonNumber(number);
        if (object instanceof Boolean bool)
            return new JsonBoolean(bool);
        if (object instanceof Collection<?> collection)
            return new JsonCollection((Collection<Object>) collection);
        return new JsonObject(object);
    }

    /**
     * 构建一个Json对象
     *
     * @param map 需要创建的数据
     */
    public static Json create(Map<?, ?> map) {
        if (map == null)
            return new JsonNull();
        return new JsonMap((Map<Object, Object>) map);
    }

    /**
     * 构建一个Json对象
     *
     * @param list 需要创建的数据
     */
    public static Json create(List<?> list) {
        if (list == null)
            return new JsonNull();
        return new JsonList((List<Object>) list);
    }

    /**
     * 构建一个Json对象
     *
     * @param collection 需要创建的数据
     */
    public static Json create(Collection<?> collection) {
        if (collection == null)
            return new JsonNull();
        return new JsonCollection((Collection<Object>) collection);
    }

    /**
     * 构建一个Json对象
     *
     * @param number 需要创建的数据
     */
    public static Json create(Number number) {
        if (number == null)
            return new JsonNull();
        return new JsonNumber(number);
    }

    /**
     * 构建一个Json对象
     *
     * @param bool 需要创建的数据
     */
    public static Json create(Boolean bool) {
        if (bool == null)
            return new JsonNull();
        return new JsonBoolean(bool);
    }

    /**
     * 构建一个Json对象
     *
     * @param string 需要创建的数据
     */
    public static Json create(CharSequence string) {
        if (string == null)
            return new JsonNull();
        return new JsonString(string);
    }


    /**
     * 解析Json字符串，并返回Json对象
     *
     * @param file 需要读取并解析的文件
     * @return 无论解析是否成功，都会返回Json对象，对于解析失败时，会保留已经解析成功的值并返回
     */
    public static Json parse(File file) {
        try {
            return parse(SuperFile.readText(file));
        } catch (IOException e) {
            return new JsonNull();
        }
    }

    /**
     * 解析Json字符串，并返回Json对象
     * <p>
     * 使用方法：传入一个需要解析的Json字符串，然后就可以使用Json对象来获取这些数据了
     *
     * @param string 需要解析的Json字符串
     * @return 无论解析是否成功，都会返回Json对象，对于解析失败时，会保留已经解析成功的值并返回
     */
    public static Json parse(String string) {
        if (string == null)
            return new JsonNull();
        return create(parse(new StringAnalysis(string.toCharArray())));
    }

    /**
     * 递归解析Json字符串
     *
     * @param analysis Json解析类，解析过程中需要使用这个类来解析字符串
     * @return Json对象
     */
    private static Object parse(StringAnalysis analysis) {
        Character character = analysis.nextNotNull(null);
        if (character == null)
            return null;
        char c = character;
        if (c == '\"' || c == '\'')
            return analysis.nextString(c);
        if (c == '{')
            return analysisMap(analysis);
        if (c == '[')
            return analysisArray(analysis);
        analysis.reset();
        return analysisConstant(analysis);
    }

    /**
     * 解析键值对，直到匹配到符号不为,
     *
     * @param analysis Json解析对象
     * @return Json键值对
     */
    private static HashMap<String, Object> analysisMap(StringAnalysis analysis) {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        while (analysis.hashNext()) {
            Character character = analysis.nextNotNull(null);
            if (character == null)
                return map;
            char c = character;
            if (c == '}')
                break;
            String key;
            if (c == '\"' || c == '\'') {
                key = analysis.nextString(c).trim();
                if (analysis.nextNotNull(' ') != ':')
                    return map;
            } else {
                analysis.reset();
                key = analysis.nextString(':').trim();
            }
            Object value = parse(analysis);
            if (key.length() > 0)
                map.put(key, value);
            if (analysis.nextNotNull(' ') != ',')
                break;
        }
        return map;
    }

    /**
     * 解析数组，直到匹配到符号不为,
     *
     * @param analysis Json解析对象
     * @return Json数组
     */
    private static ArrayList<Object> analysisArray(StringAnalysis analysis) {
        ArrayList<Object> array = new ArrayList<>();
        while (analysis.hashNext()) {
            Character character = analysis.nextNotNull(null);
            if (character == null)
                return array;
            char c = character;
            if (c == ']')
                break;
            if (c != ',')
                analysis.reset();
            array.add(parse(analysis));
        }
        return array;
    }


    /**
     * 解析常量，比如true、false、null、数字等内容
     *
     * @param analysis Json解析对象
     * @return 解析后的数据
     */
    private static Object analysisConstant(StringAnalysis analysis) {
        StringBuilder constant = new StringBuilder();
        boolean isNumber = false;
        boolean isDouble = false;
        while (analysis.hashNext()) {
            char c = analysis.next();
            if (c == ',' || c == ']' || c == '}') {
                analysis.reset();
                break;
            }
            if (c == '-') {
                constant.append(c);
                continue;
            }
            if (c == '.') {
                if (isDouble)
                    return null;
                constant.append(c);
                isDouble = true;
                continue;
            }
            if (c >= '0' && c <= '9') {
                constant.append(c);
                isNumber = true;
                continue;
            }
            constant.append(c);
        }
        String string = constant.toString().trim();
        if (isNumber) {
            try {
                return isDouble ? new BigDecimal(string) : new BigInteger(string);
            } catch (Exception ignored) {
            }
        }
        return switch (string.toLowerCase()) {
            case "true" -> true;
            case "false" -> false;
            case "nan" -> 0;
            case "null", "undefined" -> null;
            default -> string;
        };
    }


    /**
     * 获取原数据，这个数据不一定是调用者设置的值，因为在构造函数里会对一些数据进行转换.
     * <p>
     * 使用方法：该函数用于获取除构造函数外，未经任何转换的值，方便调用者自行操作数据
     *
     * @return 原数据
     */
    public abstract Object getData();

    /**
     * 设置数据
     *
     * @param data 需要设置的数据
     * @return 是否设置成功
     */
    abstract boolean setData(Object data);

    /**
     * 将数据填充到一个以及实例化的对象中
     *
     * @param original 需要填充的对象
     * @return 是否填充成功
     */
    public boolean fillInstance(Object original) {
        if (original == null)
            return false;
        Translate.fill(original, getData());
        return true;
    }

    /**
     * 实例化对象数据
     *
     * @param cls 需要实例化的类
     * @param <T> 类对象class
     * @return 实例化并填充的类对象
     */
    public <T> T newInstance(Class<T> cls) {
        if (cls == null)
            throw new NullPointerException("类型不能为空: cls = null");
        if (getData() == null)
            return null;
        if (Map.class.isAssignableFrom(cls))
            return (T) Translate.translate(getData(), new GenericityType(cls, String.class, Object.class));
        if (Collection.class.isAssignableFrom(cls))
            return (T) Translate.translate(getData(), new GenericityType(cls, Object.class));
        return (T) Translate.translate(getData(), cls);
    }

    /**
     * 实例化对象数组
     *
     * @param cls 需要实例化的类
     * @param <T> 类对象class
     * @return 实例化并填充的类数组
     */
    public <T> T[] newInstanceArray(Class<T> cls) {
        if (cls == null)
            throw new NullPointerException("类型不能为空: cls = null");
        if (getData() == null)
            return null;
        return (T[]) Translate.translate(getData(), cls.arrayType());
    }

    /**
     * 实例化对象列表
     *
     * @param cls 需要实例化的类
     * @param <T> 类对象class
     * @return 实例化并填充的类对象集合
     */
    public <T> ArrayList<T> newInstanceList(Class<T> cls) {
        if (cls == null)
            throw new NullPointerException("类型不能为空: cls = null");
        if (getData() == null)
            return null;
        return (ArrayList<T>) Translate.translate(getData(), new GenericityType(ArrayList.class, cls));
    }

    /**
     * 设置对象或键值对的值，该函数由Json调用，会保证key值不为null
     *
     * @param key   需要设置的值的键，不为null
     * @param value 需要设置的值
     * @return 是否设置成功
     */
    abstract boolean setValue(String key, Object value);

    /**
     * 设置键值对的值
     *
     * @param key   键
     * @param value 值
     * @return 如果data为null或类型为基本数据类型、数组、集合则返回false，否则返回true
     */
    public boolean set(String key, Object value) {
        if (key == null)
            throw new IllegalArgumentException("键不能为空");
        return setValue(key, value);
    }

    /**
     * 设置数组或列表对的值，该函数由Json调用
     *
     * @param index 需要设置的值的下标
     * @param value 需要设置的值
     * @return 是否设置成功
     */
    abstract boolean setValue(int index, Object value);

    /**
     * 设置数组、列表的值，如果下标越界不会报错，但会返回false
     *
     * @param index 需要设置的值的下标
     * @param value 需要设置的值
     * @return 如果设置成功则返回true，否则返回false
     */
    public boolean set(int index, Object value) {
        return setValue(index, value);
    }

    /**
     * 获取对象或键值对的值，该函数由Json调用
     *
     * @param key 需要获取的值的键
     * @return 获取的值
     */
    abstract Object getValue(String key);

    /**
     * 获取对象的值
     *
     * @param key 对象的键
     * @return 值
     */
    public Json get(String key) {
        return create(getValue(key));
    }

    /**
     * 根据下标获取数组、列表、集合的值
     *
     * @param index 要获取的值的下标
     * @return 获取的值
     */
    abstract Object getValue(int index);

    /**
     * 根据下标获取数组、列表、集合的值，如果下标越界不会报错，但会返回空值
     * <p>
     * 无论值是什么，都会返回Json对象
     *
     * @param index 要获取的值的下标
     * @return 获取的值
     */
    public Json get(int index) {
        return create(getValue(index));
    }


    /**
     * 删除一个对象或Map的值
     *
     * @param key 需要删除的值的键
     * @return 删除的值
     */
    public abstract Object removeValue(String key);

    /**
     * 删除一个对象或Map的值
     *
     * @param key 需要删除的值的键
     * @return 删除的值
     */
    public Json remove(String key) {
        return create(removeValue(key));
    }


    /**
     * 删除数组或列表中的值
     *
     * @param index 需要删除的值的下标
     * @return 删除的值
     */
    public abstract Object removeValue(int index);

    /**
     * 删除数组或列表中的值
     *
     * @param index 需要删除的值的下标
     * @return 删除的值
     */
    public Json remove(int index) {
        return create(removeValue(index));
    }

    /**
     * 将对象追踪的数据填充进来
     *
     * @param data 填充数据
     * @return 是否填充成功
     */
    public boolean fill(Object data) {
        if (data == null)
            return false;
        Object original = getData();
        if (original == null)
            return false;
        original = Translate.fill(original, data);
        if (original == null)
            return false;
        return setData(original);
    }

    /**
     * 尝试获取boolean对象
     *
     * @return boolean对象
     */
    abstract Boolean getBooleanValue();

    /**
     * 尝试获取number对象
     *
     * @return number对象
     */
    abstract Number getNumberValue();

    /**
     * 将当前数据转换成boolean对象
     *
     * @return 如果当前数据为boolean对象，则返回boolean对象，否则返回null
     */
    public Boolean getBooleanObject() {
        return getBooleanValue();
    }

    /**
     * 将当前数据转换成byte对象
     *
     * @return 如果当前数据为数字类型，则返回byte值对象，否则返回null
     */
    public Byte getByteObject() {
        Number number = getNumberValue();
        return number != null ? number.byteValue() : null;
    }

    /**
     * 将当前数据转换成short对象
     *
     * @return 如果当前数据为数字类型，则返回short值对象，否则返回null
     */
    public Short getShortObject() {
        Number number = getNumberValue();
        return number != null ? number.shortValue() : null;
    }

    /**
     * 将当前数据转换成int对象
     *
     * @return 如果当前数据为数字类型，则返回int值对象，否则返回null
     */
    public Integer getIntObject() {
        Number number = getNumberValue();
        return number != null ? number.intValue() : null;
    }

    /**
     * 将当前数据转换成long对象
     *
     * @return 如果当前数据为数字类型，则返回long值对象，否则返回null
     */
    public Long getLongObject() {
        Number number = getNumberValue();
        return number != null ? number.longValue() : null;
    }

    /**
     * 将当前数据转换成float对象
     *
     * @return 如果当前数据为数字类型，则返回float值对象，否则返回null
     */
    public Float getFloatObject() {
        Number number = getNumberValue();
        return number != null ? number.floatValue() : null;
    }

    /**
     * 将当前数据转换成double对象
     *
     * @return 如果当前数据为数字类型，则返回double值对象，否则返回null
     */
    public Double getDoubleObject() {
        Number number = getNumberValue();
        return number != null ? number.doubleValue() : null;
    }

    /**
     * 将当前数据转换成boolean值
     *
     * @return 如果当前数据为boolean对象，则返回boolean值，否则返回默认值
     */
    public boolean getBoolean(boolean defaultValue) {
        Boolean bool = getBooleanValue();
        return bool != null ? bool : defaultValue;
    }

    /**
     * 将当前数据转换成byte值
     *
     * @return 如果当前数据为数字类型，则返回byte值，否则返回默认值
     */
    public byte getByte(byte defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.byteValue() : defaultValue;
    }

    /**
     * 将当前数据转换成short对象
     *
     * @return 如果当前数据为数字类型，则返回short值，否则返回默认值
     */
    public short getShort(short defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.shortValue() : defaultValue;
    }

    /**
     * 将当前数据转换成int对象
     *
     * @return 如果当前数据为数字类型，则返回int值对象，否则返回默认值
     */
    public int getInt(int defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.intValue() : defaultValue;
    }

    /**
     * 将当前数据转换成long对象
     *
     * @return 如果当前数据为数字类型，则返回long值对象，否则返回默认值
     */
    public long getLong(long defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.longValue() : defaultValue;
    }

    /**
     * 将当前数据转换成float对象
     *
     * @return 如果当前数据为数字类型，则返回float值对象，否则返回默认值
     */
    public float getFloat(float defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.floatValue() : defaultValue;
    }

    /**
     * 将当前数据转换成double对象
     *
     * @return 如果当前数据为数字类型，则返回double值对象，否则返回默认值
     */
    public double getDouble(double defaultValue) {
        Number number = getNumberValue();
        return number != null ? number.doubleValue() : defaultValue;
    }

    /**
     * 将当前数据转换成BigInteger对象
     *
     * @return 如果当前数据为数字类型，则返回BigInteger对象，否则返回null
     */
    public BigInteger getBigInteger() {
        Number number = getNumberValue();
        if (number == null)
            return null;
        if (number instanceof BigInteger bigInteger)
            return bigInteger;
        if (number instanceof BigDecimal bigDecimal)
            return bigDecimal.toBigInteger();
        return new BigInteger(String.valueOf(number.longValue()));
    }

    /**
     * 将当前数据转换成BigDecimal对象
     *
     * @return 如果当前数据为数字类型，则返回BigDecimal对象，否则返回null
     */
    public BigDecimal getBigDecimal() {
        Number number = getNumberValue();
        if (number == null)
            return null;
        if (number instanceof BigDecimal bigDecimal)
            return bigDecimal;
        if (number instanceof BigInteger bigInteger)
            return new BigDecimal(bigInteger);
        return new BigDecimal(String.valueOf(number));
    }

    /**
     * 尝试获取字符串值
     *
     * @return 字符串值
     */
    abstract CharSequence getCharSequenceValue();

    /**
     * 将当前数据转换成String对象
     *
     * @return 如果值为字符串则返回字符串的值，否则返回null
     */
    public String getString() {
        CharSequence charSequence = getCharSequenceValue();
        return charSequence == null ? null : charSequence.toString();
    }

    /**
     * 将当前数据转换成StringBuffer对象
     *
     * @return 如果值为字符串则返回字符串的值，否则返回null
     */
    public StringBuffer getStringBuffer() {
        CharSequence charSequence = getCharSequenceValue();
        if (charSequence instanceof StringBuffer string)
            return string;
        return charSequence == null ? null : new StringBuffer(charSequence.toString());
    }

    /**
     * 将当前数据转换成StringBuilder对象
     *
     * @return 如果值为字符串则返回字符串的值，否则返回null
     */
    public StringBuilder getStringBuilder() {
        CharSequence charSequence = getCharSequenceValue();
        if (charSequence instanceof StringBuilder string)
            return string;
        return charSequence == null ? null : new StringBuilder(charSequence.toString());
    }

    /**
     * 将当前数据转换成HashMap对象
     *
     * @return 如果值为HashMap则创建并返回，如果为对象则将对象反射成HashMap，否则返回null
     */
    public abstract HashMap<String, Object> getHashMap();

    /**
     * 将当前数据转换成ArrayList对象
     *
     * @return 如果值为Collection的子类或数组则创建并返回，否则返回null
     */
    public abstract ArrayList<Object> getArrayList();

    /**
     * 判断数据是否null
     *
     * @return 是否null
     */
    public boolean isNull() {
        return getData() == null;
    }

    /**
     * 序列化字符串
     *
     * @param string    序列化后的字符串
     * @param data      需要序列化的字符串
     * @param unicode   是否将非ascii码的字符转换成unicode编码
     * @param nonEscape 不使用转义字符，如缩进、回车等字符保持不变
     */
    private static void stringifyString(StringBuilder string, String data, boolean unicode, boolean nonEscape) {
        if (unicode)
            string.append(N.encodeUnicode(data, nonEscape ? TRANSLATE_DISABLED : TRANSLATE_ENABLE));
        else if (nonEscape) {
            for (char c : data.toCharArray()) {
                if (c == '"')
                    string.append("\\\"");
                else
                    string.append(c);
            }
        } else
            for (char c : data.toCharArray())
                string.append(TRANSLATE_ENABLE.translate(c));
    }

    /**
     * 序列化Json字符串
     *
     * @param string    序列化字符串
     * @param data      需要序列化的数据
     * @param retract   缩进
     * @param unicode   是否将非ascii码的字符转换成unicode编码
     * @param nonEscape 不使用转义字符，如缩进、回车等字符保持不变
     * @param empty     包含值为null的键值对
     */
    static void stringify(StringBuilder string, Object data, Retract retract, boolean unicode, boolean nonEscape, boolean empty) {
        if (data == null) {
            string.append("null");
            return;
        }
        while (data instanceof Json json)
            data = json.getData();
        if (data instanceof Date date) {
            string.append('"').append(N.dateFormat.format(date)).append('"');
            return;
        }
        if (data instanceof Number || data instanceof Boolean) {
            string.append(data);
            return;
        }
        if (data instanceof CharSequence) {
            string.append('"');
            stringifyString(string, data.toString(), unicode, nonEscape);
            string.append('"');
            return;
        }
        var array = Translate.parseArray(data);
        if (array != null) {
            string.append('[');
            boolean interval = false;
            for (Object object : array) {
                if (interval)
                    string.append(retract.isEnable() ? ", " : ",");
                else
                    interval = true;
                stringify(string, object, retract, unicode, nonEscape, empty);
            }
            string.append(']');
            return;
        }
        var map = Translate.parseMap(data);
        if (map == null) {
            string.append("null");
            return;
        }
        retract.add(1);
        string.append('{');
        boolean interval = false;
        for (var entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (!empty && (key == null || value == null))
                continue;
            if (interval)
                string.append(retract.isEnable() ? ",\n" : ",");
            else {
                if (retract.isEnable())
                    string.append('\n');
                interval = true;
            }
            string.append(retract.get());
            string.append('"');
            stringifyString(string, key, unicode, nonEscape);
            string.append('"');
            string.append(retract.isEnable() ? ": " : ":");
            stringify(string, value, retract, unicode, nonEscape, empty);
        }
        retract.add(-1);
        if (interval && retract.isEnable()) {
            string.append('\n');
            string.append(retract.get());
        }
        string.append('}');
    }

    /**
     * 序列化Json字符串
     *
     * @param data   需要序列化的对象
     * @param string 序列化字符串
     * @param config 上下文配置，如格式化Json代码、非ASCII码转换为unicode编码等
     */
    public static void stringify(Object data, StringBuilder string, int config) {
        if (string == null)
            throw new NullPointerException("StringBuilder字符串不能为空");
        stringify(string, data, new Retract() {{
                    setEnable((config & CONFIG_FORMAT) == CONFIG_FORMAT);
                }}, (config & CONFIG_UNICODE) == CONFIG_UNICODE,
                (config & CONFIG_NON_ESCAPE) == CONFIG_NON_ESCAPE,
                (config & CONFIG_EMPTY) == CONFIG_EMPTY);
    }

    /**
     * 序列化Json字符串
     *
     * @param string 序列化字符串
     * @param config 上下文配置，如格式化Json代码、非ASCII码转换为unicode编码等
     */
    public void stringify(StringBuilder string, int config) {
        stringify(getData(), string, config);
    }

    /**
     * 序列化Json字符串
     *
     * @param data   需要序列化的对象
     * @param config 上下文配置，如格式化Json代码、非ASCII码转换为unicode编码等
     * @return 序列化后的字符串
     */
    public static String stringify(Object data, int config) {
        StringBuilder string = new StringBuilder();
        stringify(data, string, config);
        return string.toString();
    }

    /**
     * 序列化Json字符串
     *
     * @param config 上下文配置，如格式化Json代码、非ASCII码转换为unicode编码等
     * @return 序列化后的字符串
     */
    public String stringify(int config) {
        return stringify(getData(), config);
    }

    /**
     * 序列化Json字符串
     *
     * @param data 需要序列化的对象
     * @return 序列化后的字符串
     */
    public static String stringify(Object data) {
        return stringify(data, 0);
    }

    /**
     * 序列化Json字符串
     *
     * @return 序列化后的字符串
     */
    public String stringify() {
        return stringify(getData());
    }

    /**
     * 序列化Json字符串，并且将字符串格式化，一般用作调试输出
     *
     * @param data 需要序列化的对象
     * @return 序列化后的字符串
     */
    public static String stringifyFormat(Object data) {
        return stringify(data, CONFIG_FORMAT);
    }

    /**
     * 序列化Json字符串，并且将字符串格式化
     *
     * @return 序列化后的字符串
     */
    public String stringifyFormat() {
        return stringifyFormat(getData());
    }

    /**
     * 序列化Json字符串，并且将非ascii的字符转换成unicode
     *
     * @param data 需要序列化的对象
     * @return 序列化后的字符串
     */
    public static String stringifyUnicode(Object data) {
        return stringify(data, CONFIG_UNICODE);
    }

    /**
     * 序列化Json字符串，并且将非ascii的字符转换成unicode
     *
     * @return 序列化后的字符串
     */
    public String stringifyUnicode() {
        return stringifyUnicode(getData());
    }

    /**
     * 序列化Json字符串，并且不忽略Map的空值
     *
     * @param data 需要序列化的对象
     * @return 序列化后的字符串
     */
    public static String stringifyEmpty(Object data) {
        return stringify(data, CONFIG_EMPTY);
    }

    /**
     * 序列化Json字符串，并且不忽略Map的null值
     *
     * @return 序列化后的字符串
     */
    public String stringifyEmpty() {
        return stringifyEmpty(getData());
    }

    /**
     * 序列化字符串，将用作调试和打印，如需序列化请调用stringify函数
     *
     * @return 序列化后的Json字符串
     */
    @Override
    public String toString() {
        return stringifyEmpty();
    }
}
